package hc.bre.rest.manage
import hc.bre.*
import hc.bre.cmn.*
import hc.bre.project.ProjectDefinition
import hc.bre.rest.admin.*
import hc.bre.rest.cmn.IgnoreReponseAdvice
import javax.annotation.PostConstruct
import org.apache.shiro.SecurityUtils
import org.apache.shiro.authc.*
import org.apache.shiro.authz.AuthorizationException
import org.apache.shiro.authz.annotation.RequiresPermissions
import org.apache.shiro.realm.Realm
import org.apache.shiro.subject.Subject
import org.slf4j.*
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.*
import org.springframework.web.client.RestTemplate

@groovy.transform.CompileStatic
@RestController
@RequestMapping("/manage")
class MainController {
	protected static final Logger _log = LoggerFactory.getLogger(MainController.class);
	@Autowired
	MainService mainService;

	@RequestMapping("/loadConfig")
	public Object loadConfig(){
		return new ThisApplicationConfig();
	}

	@RequestMapping("/loadProject")
	public Object loadProject(@RequestParam String rpath){
		AuthUtil.permit(rpath,BrePermission.read) {
			return  mainService.loadProject(rpath);
		}
	}

	@RequestMapping("/createProject")
	public Object createProject(@RequestBody Map map){
		AuthUtil.permit(map['rpath'] as String,BrePermission.read) {
			return  mainService.createProject(map)
		}
	}
	
	@RequestMapping("/deleteProject")
	public Object deleteProject(@RequestParam String rpath){
		AuthUtil.permit(rpath,BrePermission.delete) {
			return mainService.deleteProject(rpath);
		}
	}

	@RequestMapping("/updateProject")
	public Object updateProject(@RequestBody Map map){
		AuthUtil.permit(map['rpath'] as String,BrePermission.read) {
			return  mainService.updateProject(map)
		}
	}

	//arguments: rtype rname rpath
	@PostMapping("/create")
	public RuleDefinition createRuleDef(@RequestBody Map map){
		AuthUtil.permit(map['rpath'] as String,BrePermission.read)
		{
			return  mainService.createRuleDef(map)
		}
	};

	@GetMapping("/loadByRpath")
	public RuleDefinition loadRuleDef(@RequestParam String rpath){
		AuthUtil.permit(rpath,BrePermission.read)
		{
			return mainService.loadRuleDef(rpath)
		}
	}

	@RequestMapping("/projectList")
	public List<ProjectEntry> projectList(){
		List<ProjectEntry> lst = BreAdminConfig.config.projectList
		lst = lst.findAll {
			AuthUtil.isPermitted(it.rpath,BrePermission.read)
		}
		return lst;
	}

	@RequestMapping("/funcList")
	public Object funcList(){
		def r= FunctionConfig.list.findAll {
			return AuthUtil.isFuncPermitted(it.perm);
		};
		return r;
	}

	@PostMapping("/update")
	public RuleDefinition updateRuleDef(@RequestBody Map map){
		AuthUtil.permit(map['rpath'] as String,BrePermission.update)
		{
			return mainService.updateRuleDef(map)
		}
	}

	@RequestMapping("/delete")
	public Object deleteRuleDef(@RequestParam String rpath){
		AuthUtil.permit(rpath,BrePermission.delete)
		{
			return mainService.deleteRuleDef(rpath)
		}
	}

	@RequestMapping("/groovy")
	public Object groovyOfRule(@RequestParam String rpath){
		AuthUtil.permit(rpath,BrePermission.read)
		{
			return mainService.singleScriptOfProject(rpath)
		}
	}

	@PostMapping("/importProj")
	public Object importProj(@RequestBody Map projDef){
		AuthUtil.permit(projDef.rpath as String,BrePermission.update)
		{
			return mainService.importProj(projDef);
		}

	}

	@PostMapping("/compareProj")
	public Object compareProj(@RequestBody Map request){
		RestTemplate restTemplate = new RestTemplate();

		HashMap res ;
		res = restTemplate.postForObject("${request.host}/api/downloadProj",
				[appKey:request.appKey,appSecret:request.appSecret,rpath:request.rpath], HashMap);

		if(res.error)
		{
			throw new BreException(res.data?.toString());
		}

		AuthUtil.permit(request.rpath as String,BrePermission.read)
		{
			return mainService.compareProj(request.rpath as String,res.data as Map);
		}
	}

	@PostMapping("/publishProj")
	public Object uploadProj(@RequestBody Map request){
		RestTemplate restTemplate = new RestTemplate();

		AuthUtil.permit(request.rpath as String,BrePermission.read)
		{
			ProjectDefinition projDef = mainService.loadProject(request.rpath as String);
			HashMap res ;
			res = restTemplate.postForObject("${request.host}/api/publishProj",
					[appKey:request.appKey,appSecret:request.appSecret,data:projDef], HashMap);

			println res;
			return res;
		}

	}
}
